import {isEmpty} from 'ramda';
import { Suspense, lazy, useMemo } from 'react';
import { Navigate, Outlet } from 'react-router-dom';

import { Iconify } from '@/components/icon';
import { CircleLoading } from '@/components/loading';
import { useUserPermission } from '@/store/userStore';
import ProTag from '@/theme/antd/components/tag';
import { flattenTrees } from '@/utils/tree';

import { BasicStatus, PermissionType } from '@/constants/layout';

const ENTRY_PATH = '/src/pages';
const PAGES = import.meta.glob('/src/pages/**/*.tsx');
const loadComponentFromPath = (path) => PAGES[`${ENTRY_PATH}${path}`];

/**
 * Build complete route path by traversing from current permission to root
 * @param {Permission} permission - current permission
 * @param {Permission[]} flattenedPermissions - flattened permission array
 * @param {string[]} segments - route segments accumulator
 * @returns {string} normalized complete route path
 */
function buildCompleteRoute(
  permission,
  flattenedPermissions,
  segments = [],
) {
  // Add current route segment
  segments.unshift(permission.route);

  // Base case: reached root permission
  if (!permission.parentId) {
    return `/${segments.join('/')}`;
  }

  // Find parent and continue recursion
  const parent = flattenedPermissions.find((p) => p.id === permission.parentId);
  if (!parent) {
    console.warn(`Parent permission not found for ID: ${permission.parentId}`);
    return `/${segments.join('/')}`;
  }

  return buildCompleteRoute(parent, flattenedPermissions, segments);
}

// Components
function NewFeatureTag() {
  return (
    <ProTag color="cyan" icon={<Iconify icon="solar:bell-bing-bold-duotone" size={14} />}>
      NEW
    </ProTag>
  );
}

function RouteWrapper({ children }) {
  return <Suspense fallback={<CircleLoading />}>{children}</Suspense>;
}

// Route Transformers
const createBaseRoute = (permission, completeRoute) => {
  const { route, label, icon, order, hide, hideTab, status, frameSrc, newFeature } = permission;

  const baseRoute = {
    path: route,
    meta: {
      label,
      key: completeRoute,
      hideMenu: !!hide,
      hideTab,
      disabled: status === BasicStatus.DISABLE,
    },
  };

  if (order) baseRoute.order = order;
  if (icon) baseRoute.meta.icon = icon;
  if (frameSrc) baseRoute.meta.frameSrc = frameSrc;
  if (newFeature) baseRoute.meta.suffix = <NewFeatureTag />;

  return baseRoute;
};

const createCatalogueRoute = (
  permission,
  flattenedPermissions,
) => {
  const baseRoute = createBaseRoute(
    permission,
    buildCompleteRoute(permission, flattenedPermissions),
  );

  baseRoute.meta.hideTab = true;

  const { parentId, children = [] } = permission;
  if (!parentId) {
    baseRoute.element = (
      <RouteWrapper>
        <Outlet />
      </RouteWrapper>
    );
  }

  baseRoute.children = transformPermissionsToRoutes(children, flattenedPermissions);

  if (!isEmpty(children)) {
    baseRoute.children.unshift({
      index: true,
      element: <Navigate to={children[0].route} replace />,
    });
  }

  return baseRoute;
};

const createMenuRoute = (
  permission,
  flattenedPermissions,
) => {
  const baseRoute = createBaseRoute(
    permission,
    buildCompleteRoute(permission, flattenedPermissions),
  );

  const Element = lazy(loadComponentFromPath(permission.component));

  baseRoute.element = permission.frameSrc ? (
    <Element src={permission.frameSrc} />
  ) : (
    <RouteWrapper>
      <Element />
    </RouteWrapper>
  );

  return baseRoute;
};

// Main Functions
function transformPermissionsToRoutes(
  permissions,
  flattenedPermissions,
) {
  return permissions.map((permission) => {
    if (permission.type === PermissionType.CATALOGUE) {
      return createCatalogueRoute(permission, flattenedPermissions);
    }
    return createMenuRoute(permission, flattenedPermissions);
  });
}

// Exports
export function usePermissionRoutes() {
  // return useMemo(() => {
  //   return getRoutesFromModules();
  // }, []);

  const permissions = useUserPermission();
  return useMemo(() => {
    if (!permissions) return [];

    const flattenedPermissions = flattenTrees(permissions);
    return transformPermissionsToRoutes(permissions, flattenedPermissions);
  }, [permissions]);
}
